<template>
  <div class="image-video-upload">
    <el-upload
      class="upload-container"
      action="/api/upload"
      :show-file-list="true"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :before-upload="beforeUpload"
      :limit="limit"
      :on-exceed="onExceed"
      multiple
      :file-list="fileList"
    >
      <div class="upload-trigger">
        <el-icon :size="24"><Plus /></el-icon>
        <div class="upload-text">点击上传图片/视频</div>
        <div class="upload-hint">
          支持jpg、png、mp4格式，单个文件不超过{{ formatFileSize(maxSize) }}
        </div>
      </div>
    </el-upload>

    <!-- 预览图片的对话框 -->
    <el-dialog v-model="previewVisible" append-to-body>
      <img :src="previewUrl" alt="Preview" class="w-full" />
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";
import { Plus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => [],
  },
  limit: {
    type: Number,
    default: 9,
  },
  maxSize: {
    type: Number,
    default: 10 * 1024 * 1024, // 10MB
  },
});

const emit = defineEmits(["update:modelValue", "exceed"]);

const previewVisible = ref(false);
const previewUrl = ref("");

const fileList = computed({
  get: () => props.modelValue,
  set: (val) => emit("update:modelValue", val),
});

const handlePreview = (file) => {
  previewUrl.value = file.url;
  previewVisible.value = true;
};

const handleRemove = (file, fileList) => {
  emit("update:modelValue", fileList);
};

const handleSuccess = (response, file, fileList) => {
  emit("update:modelValue", fileList);
};

const beforeUpload = (file) => {
  const isImage = /^image\/(jpeg|png|gif)$/.test(file.type);
  const isVideo = file.type === "video/mp4";
  const isLt10M = file.size <= props.maxSize;

  if (!isImage && !isVideo) {
    ElMessage.error("只能上传jpg/png/gif图片或mp4视频！");
    return false;
  }
  if (!isLt10M) {
    ElMessage.error(`文件大小不能超过 ${formatFileSize(props.maxSize)}！`);
    return false;
  }
  return true;
};

const onExceed = (files) => {
  ElMessage.warning(`最多只能上传 ${props.limit} 个文件`);
  emit("exceed", files);
};

const formatFileSize = (bytes) => {
  if (bytes === 0) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB", "TB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};
</script>

<style lang="scss" scoped>
.image-video-upload {
  .upload-container {
    :deep(.el-upload) {
      @apply w-full;
    }

    :deep(.el-upload-list) {
      @apply mt-4;

      .el-upload-list__item {
        @apply dark:bg-gray-700 dark:text-gray-100 dark:border-gray-600 
               transition-colors duration-300;

        &:hover {
          @apply dark:bg-gray-600;
        }

        .el-upload-list__item-name {
          @apply dark:text-gray-300;
        }

        .el-icon {
          @apply dark:text-gray-400;

          &:hover {
            @apply dark:text-gray-200;
          }
        }
      }
    }
  }

  .upload-trigger {
    @apply border-2 border-dashed border-gray-200 dark:border-gray-700 
           hover:border-primary-500 dark:hover:border-primary-500
           bg-white dark:bg-gray-800
           rounded-lg p-6 cursor-pointer
           flex flex-col items-center justify-center
           transition-colors duration-300;

    .el-icon {
      @apply text-gray-400 dark:text-gray-500 mb-2;
    }

    .upload-text {
      @apply text-gray-600 dark:text-gray-300 text-sm mb-1;
    }

    .upload-hint {
      @apply text-gray-400 dark:text-gray-500 text-xs;
    }

    &:hover {
      @apply border-primary-500;

      .el-icon {
        @apply text-primary-500;
      }

      .upload-text {
        @apply text-primary-500;
      }
    }
  }
}

:deep(.el-dialog) {
  @apply dark:bg-gray-800;

  .el-dialog__header {
    @apply dark:bg-gray-800;
  }

  .el-dialog__body {
    @apply dark:bg-gray-800;
  }
}
</style>
